package com.yao.seckill.web.utils;

import com.alibaba.fastjson.JSONObject;
import com.yao.seckill.web.service.RabbitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Copyright (C), 2022-2022, 姚兵
 * Author: 32210
 * Date: 2022/9/16 15:23
 * FileName: RabbitUtils
 * Description: rabbit
 */
@Component
@Slf4j
public class RabbitUtils implements InitializingBean {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    RabbitService rabbitService;

    @Override
    public void afterPropertiesSet() throws Exception {
        /*
         * 当mandatory标志位设置为true时
         * 如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息
         * 那么broker会调用basic.return方法将消息返还给生产者
         * 当mandatory设置为false时，出现上述情况broker会直接将消息丢弃
         */
        rabbitTemplate.setMandatory(true);
        // 设置配置回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {

            //confirm机制只保证消息到达exchange，不保证消息可以路由到正确的queue,如果exchange错误，就会触发confirm机制
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                log.info("ConfirmCallback:     " + "相关数据：" + JSONObject.toJSONString(correlationData));
                log.info("ConfirmCallback:     " + "确认情况：" + ack);
                log.info("ConfirmCallback:     " + "原因：" + cause);
               rabbitService.saveMsgToDb(correlationData,ack,cause);
            }
        });


        //Return 消息机制用于处理一个不可路由的消息。在某些情况下，如果我们在发送消息的时候，当前的 exchange 不存在或者指定路由 key 路由不到，这个时候我们需要监听这种不可达的消息
        //   * 就需要这种return机制
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {

            @Override
            public void returnedMessage(ReturnedMessage returned) {
                log.info("ReturnCallback:     " + "消息：" + returned.getMessage());
                log.info("ReturnCallback:     " + "回应码：" + returned.getReplyCode());
                log.info("ReturnCallback:     " + "回应信息：" + returned.getReplyText());
                log.info("ReturnCallback:     " + "交换机：" + returned.getExchange());
                log.info("ReturnCallback:     " + "路由键：" + returned.getRoutingKey());
            }
        });
    }


}
